Cara Membuat Fitur Verifikasi Menggunakan OTP

Posted on 22 August 2024


Untuk menyiapkan fitur verifikasi menggunakan OTP di Laravel, Anda perlu memastikan bahwa konfigurasi .env Anda sudah tepat, terutama untuk pengiriman email. Berikut adalah pengaturan yang perlu Anda tambahkan atau sesuaikan dalam file .env Anda:

MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-email-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=your-email@gmail.com
MAIL_FROM_NAME="${APP_NAME}"

Untuk membuat fitur verifikasi menggunakan OTP (One-Time Password) di Laravel, Anda dapat mengikuti langkah-langkah berikut:

1. Buat Table untuk Menyimpan OTP

Buat migration baru untuk menyimpan OTP di database. OTP biasanya terkait dengan user, jadi Anda bisa menambahkan kolom di tabel users atau membuat tabel terpisah.

php artisan make:migration add_otp_to_users_table --table=users
Di file migration tersebut, tambahkan kolom-kolom yang diperlukan:
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('otp_code')->nullable();
        $table->timestamp('otp_expires_at')->nullable();
    });
}
public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn(['otp_code', 'otp_expires_at']);
    });
}
Jalankan migrasi dengan perintah:
php artisan migrate

2. Generate OTP dan kirim ke User

Buat metode di model User untuk generate OTP, simpan di database, dan kirim ke user (misalnya melalui email atau SMS).

use Illuminate\Support\Facades\Mail;
public function generateOTP()
{
    $otp = rand(100000, 999999);
    $this->otp_code = $otp;
    $this->otp_expires_at = now()->addMinutes(10); // OTP valid for 10 minutes
    $this->save();
    // Kirim OTP via email (atau SMS)
    Mail::to($this->email)->send(new OTPMail($otp));
}
Buat mail class untuk mengirimkan OTP:
php artisan make:mail OTPMail
Di OTPMail.php:
public $otp;
public function __construct($otp)
{
    $this->otp = $otp;
}
public function build()
{
    return $this->view('emails.otp')
                ->with(['otp' => $this->otp]);
}
Buat file view untuk email OTP di resources/views/emails/otp.blade.php:
<p>Kode OTP Anda adalah: {{ $otp }}</p>

3. Verifikasi OTP

Buat route dan controller untuk menangani verifikasi OTP. Contoh route:

Route::post('/verify-otp', [OTPController::class, 'verify']);
Di OTPController, buat metode verify:
public function verify(Request $request)
{
    $request->validate([
        'otp' => 'required',
    ]);
    $user = auth()->user(); // Atau cari user berdasarkan email
    if ($user->otp_code === $request->otp && $user->otp_expires_at->isFuture()) {
        // OTP valid
        $user->otp_code = null;
        $user->otp_expires_at = null;
        $user->save();
        return redirect()->route('home')->with('success', 'OTP berhasil diverifikasi.');
    }
    return back()->withErrors(['otp' => 'Kode OTP tidak valid atau sudah kadaluarsa.']);
}
4. Buat View untuk Input OTP
Buat form di Blade untuk memasukkan OTP:
<form action="{{ route('verify-otp') }}" method="POST">
    @csrf
    <input type="text" name="otp" placeholder="Masukkan OTP">
    <button type="submit">Verifikasi</button>
</form>

5. Integrasikan OTP dalam Proses Registrasi/Login

Misalnya, setelah registrasi atau login berhasil, alihkan user ke halaman input OTP untuk verifikasi.

public function register(Request $request)
{
    // Proses registrasi
    $user->generateOTP(); // Generate dan kirim OTP
    return redirect()->route('otp.form'); // Alihkan ke form OTP
}
Untuk login, pastikan user harus memasukkan OTP sebelum diizinkan masuk ke dashboard.
6. Handle Expired OTP
Anda dapat menampilkan opsi untuk mengirim ulang OTP jika sudah expired atau user tidak menerimanya.
<form action="{{ route('resend-otp') }}" method="POST">
    @csrf
    <button type="submit">Kirim Ulang OTP</button>
</form>
7. Kirim ulang OTP
Buat route dan controller untuk menangani pengiriman ulang OTP.
public function resendOTP()
{
    $user = auth()->user();
    $user->generateOTP(); // Kirim ulang OTP
    return back()->with('success', 'OTP baru telah dikirim.');
}